home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / pgp20src.zip / SYSTEM.C < prev    next >
C/C++ Source or Header  |  1992-08-17  |  14KB  |  754 lines

  1. /*
  2.  * system.c
  3.  *
  4.  * Routines specific for non-MSDOS implementations of pgp.
  5.  * 
  6.  *    Modified 24-Jun-92 HAJK
  7.  *    Adapt for VAX/VMS.
  8.  */
  9. #include <stdio.h>
  10. #include "pgp.h"
  11.  
  12.  
  13. /*===========================================================================*/
  14. /*
  15.  * UNIX
  16.  */
  17.  
  18. #ifdef UNIX
  19. /*
  20.  * Define USE_SELECT to use the select() system call to check if
  21.  * keyboard input is available. Define USE_NBIO to use non-blocking
  22.  * read(). If you don't define anything the FIONREAD ioctl() command
  23.  * will be used.
  24.  *
  25.  * Define NOTERMIO if you don't have the termios stuff
  26.  */
  27. #include <sys/types.h>
  28. #include <fcntl.h>
  29. #ifndef NeXT
  30. #include <unistd.h>
  31. #endif
  32.  
  33. #ifndef    NOTERMIO
  34. #ifndef M_XENIX
  35. #include <termios.h>
  36. #else
  37. #include <termio.h>
  38. #endif /* not M_XENIX */
  39. #else
  40. #include <sgtty.h>
  41. #endif
  42.  
  43. #ifdef    USE_SELECT
  44. #include <sys/time.h>
  45. #else
  46. #ifndef USE_NBIO
  47. #include <sys/ioctl.h>        /* for FIONREAD */
  48. #ifndef FIONREAD
  49. #define    FIONREAD    TIOCINQ
  50. #endif
  51. #endif
  52. #endif
  53. #include <signal.h>
  54.  
  55. static void setsigs(void);
  56. static void rmsigs(void);
  57. static void sig1(int);
  58. static void sig2(int);
  59. void breakHandler(int);
  60. static int ttyfd= -1;
  61. #ifndef M_XENIX
  62. static void (*savesig)(int);
  63. #else
  64. static int (*savesig)(int);
  65. #endif
  66.  
  67. void ttycbreak(void);
  68. void ttynorm(void);
  69.  
  70.  
  71. #ifndef NOTERMIO
  72. #ifndef M_XENIX
  73. static struct termios itio, tio;
  74. #else
  75. static struct termio itio, tio;
  76. #endif /* not M_XENIX */
  77. #else
  78. static struct sgttyb isg, sg;
  79. #endif
  80.  
  81. #ifdef USE_NBIO
  82. static int kbuf= -1;    /* buffer to store char read by kbhit() */
  83. static int fflags;
  84. #endif
  85.  
  86. static int gottio = 0;
  87.  
  88. void ttycbreak(void)
  89. {
  90.     if (ttyfd == -1) {
  91.         if ((ttyfd = open("/dev/tty", O_RDWR)) < 0) {
  92.             fprintf(stderr, "cannot open tty, using stdin\n");
  93.             ttyfd = 0;
  94.         }
  95.     }
  96. #ifndef NOTERMIO
  97. #ifndef M_XENIX
  98.     if (tcgetattr(ttyfd, &tio) < 0)
  99. #else
  100.     if (ioctl(ttyfd, TCGETA, &tio) < 0)
  101. #endif  /* not M_XENIX */
  102.     {    fprintf (stderr, "\nUnable to get terminal characteristics: ");
  103.         perror("ioctl");
  104.         exitPGP(1);
  105.     }
  106.     itio = tio;
  107.     setsigs();
  108.     gottio = 1;
  109. #ifdef USE_NBIO
  110.     tio.c_cc[VMIN] = 0;
  111. #else
  112.     tio.c_cc[VMIN] = 1;
  113. #endif
  114.     tio.c_cc[VTIME] = 0;
  115.     tio.c_lflag &= ~(ECHO|ICANON);
  116. #ifndef M_XENIX
  117.     tcsetattr (ttyfd, TCSAFLUSH, &tio);
  118. #else
  119.     ioctl(ttyfd, TCSETAW, &tio);
  120. #endif /* not M_XENIX */
  121. #else
  122.     if (ioctl(ttyfd, TIOCGETP, &sg) < 0)
  123.     {    fprintf (stderr, "\nUnable to get terminal characteristics: ");
  124.         perror("ioctl");
  125.         exitPGP(1);
  126.     }
  127.     isg = sg;
  128.     setsigs();
  129.     gottio = 1;
  130.     sg.sg_flags |= CBREAK;
  131.     sg.sg_flags &= ~ECHO;
  132.     ioctl(ttyfd, TIOCSETP, &sg);
  133. #endif    /* !NOTERMIO */
  134. #ifdef USE_NBIO
  135.     if ((fflags = fcntl(ttyfd, F_GETFL)) != -1)
  136.         fcntl(ttyfd, F_SETFL, fflags|O_NDELAY);
  137. #endif
  138. }
  139.  
  140.  
  141. void ttynorm(void)
  142. {    gottio = 0;
  143. #ifdef USE_NBIO
  144.     if (fcntl(ttyfd, F_SETFL, fflags) == -1)
  145.         perror("fcntl");
  146. #endif
  147. #ifndef NOTERMIO
  148. #ifndef M_XENIX
  149.     tcsetattr (ttyfd, TCSAFLUSH, &itio);
  150. #else
  151.     ioctl(ttyfd, TCSETAW, &itio);
  152. #endif /* not M_XENIX */
  153. #else
  154.     ioctl(ttyfd, TIOCSETP, &isg);
  155. #endif
  156.     rmsigs();
  157. }
  158.  
  159. static void sig1 (int sig)
  160. {
  161. #ifndef NOTERMIO
  162. #ifndef M_XENIX
  163.     tcsetattr (ttyfd, TCSANOW, &itio);
  164. #else
  165.     ioctl(ttyfd, TCSETAW, &itio);
  166. #endif /* not M_XENIX */
  167. #else
  168.     ioctl(ttyfd, TIOCSETP, &isg);
  169. #endif
  170.     signal (sig, SIG_DFL);
  171.     if (sig == SIGINT)
  172.         breakHandler(SIGINT);
  173.     kill (getpid(), sig);
  174. }
  175.  
  176. static void sig2 (int sig)
  177. {    if (gottio)
  178.         ttycbreak();
  179.     else
  180.         setsigs();
  181. }
  182.  
  183. static void setsigs(void)
  184. {    savesig = signal (SIGINT, sig1);
  185. #ifdef    SIGTSTP
  186.     signal (SIGCONT, sig2);
  187.     signal (SIGTSTP, sig1);
  188. #endif
  189. }
  190.  
  191. static void rmsigs(void)
  192. {    signal (SIGINT, savesig);
  193. #ifdef    SIGTSTP
  194.     signal (SIGCONT, SIG_DFL);
  195.     signal (SIGTSTP, SIG_DFL);
  196. #endif
  197. }
  198.  
  199. #ifndef CRUDE
  200. int kbhit(void)
  201. /* Return TRUE if there is a key to be read */
  202. {
  203. #ifdef USE_SELECT        /* use select() system call */
  204.     struct timeval t;
  205.     fd_set n;
  206.     int r;
  207.  
  208.     timerclear(&t);
  209.     FD_ZERO(&n);
  210.     FD_SET(ttyfd, &n);
  211.     r = select(32, &n, NULL, NULL, &t);
  212.     if (r == -1) {
  213.         perror("select");
  214.         exitPGP(1);
  215.     }
  216.     return r > 0;
  217. #else
  218. #ifdef    USE_NBIO        /* use non-blocking read() */
  219.     unsigned char ch;
  220.     if (kbuf >= 0) 
  221.         return(1);
  222.     if (read(ttyfd, &ch, 1) == 1) {
  223.         kbuf = ch;
  224.         return(1);
  225.     }
  226.     return(0);
  227. #else
  228.     long lf;
  229.     if (ioctl(ttyfd, FIONREAD, &lf) == -1) {
  230.         perror("ioctl: FIONREAD");
  231.         exitPGP(1);
  232.     }
  233.     return(lf);
  234. #endif
  235. #endif
  236. }
  237. #endif    /* !CRUDE */
  238.  
  239. int getch(void)
  240. {
  241.     char c;
  242. #ifdef USE_NBIO
  243.     while (!kbhit());    /* kbhit() does the reading */
  244.     c = kbuf;
  245.     kbuf = -1;
  246. #else
  247.     read(ttyfd, &c, 1);
  248. #endif
  249.     return(c);
  250. }
  251.  
  252. #ifdef BSD_OLD
  253. void *memset(s, c, n)
  254. void *s;
  255. register int c, n;
  256. {
  257.     register char *p = s;
  258.     ++n;
  259.     while (--n)
  260.         *p++ = c;
  261.     return(s);
  262. }
  263. int memcmp(s1, s2, n)
  264. register unsigned char *s1, *s2;
  265. register int n;
  266. {
  267.     if (!n)
  268.         return(0);
  269.     while (--n && *s1 == *s2) {
  270.         ++s1;
  271.         ++s2;
  272.     }
  273.     return(*s1 - *s2);
  274. }
  275. void *memcpy(s1, s2, n)
  276. register char *s1, *s2;
  277. register int n;
  278. {
  279.     char *p = s1;
  280.     ++n;
  281.     while (--n)
  282.         *s1++ = *s2++;
  283.     return(p);
  284. }
  285. #endif /* BSD_OLD */
  286.  
  287. #ifdef  M_XENIX         /* XENIX/286 specific stuff */
  288. int remove(name)
  289. char *name;
  290. {
  291.     return unlink(name);
  292. }
  293.  
  294. int rename(old, new)
  295. register char *old, *new;
  296. {
  297.     (void) unlink(new);
  298.     if (link(old, new) < 0)
  299.         return -1;
  300.     if (unlink(old) < 0) {
  301.         (void) unlink(new);
  302.         return -1;
  303.     }
  304.     return 0;
  305. }
  306. #endif /* M_XENIX */
  307. #endif /* UNIX */
  308.  
  309.  
  310.  
  311. /*===========================================================================*/
  312. /*
  313.  * VMS
  314.  */
  315.  
  316. #ifdef VMS            /* kbhit()/getch() equivalent */
  317.  
  318. /*
  319.  * This code defines an equivalent version of kbhit() and getch() for
  320.  * use under VAX/VMS, together with an exit handler to reset terminal
  321.  * characteristics.
  322.  *
  323.  * This code assumes that kbhit() has been invoked to test that there
  324.  * are characters in the typeahead buffer before getch() is invoked to
  325.  * get the answer.
  326.  */
  327.  
  328. #include <descrip.h>
  329. #include <iodef.h>
  330. #ifdef VAXC
  331. #include <ttdef.h>
  332. #include <tt2def.h>
  333. #include <dcdef.h>
  334. #else /* Probably GNU */
  335. #include <vms/$ttdef.h>
  336. #include <vms/$tt2def.h>
  337. #include <vms/$dcdef.h>
  338. #endif /* VAXC */
  339. static volatile short    _kbhitChan_ = 0;
  340.  
  341. static volatile struct IOSB {
  342.     unsigned short sts;
  343.     unsigned short byteCount;
  344.     unsigned short terminator;
  345.     unsigned short terminatorSize;
  346.     } iosb;
  347. static $DESCRIPTOR (kbdev_desc, "SYS$COMMAND:");
  348.  
  349. static volatile struct {
  350.     char Class;
  351.     char Type;
  352.     unsigned short BufferSize;
  353.     unsigned int Mode;
  354.     int ExtChar;
  355.   } CharBuf, OldCharBuf;
  356.  
  357. void kbhit_handler(int *sts)
  358. {
  359.   int mysts;
  360.  
  361.   CharBuf.Mode = OldCharBuf.Mode;
  362.   CharBuf.ExtChar = OldCharBuf.ExtChar;
  363.   CharBuf.Mode &= ~TT$M_NOECHO;
  364.   CharBuf.ExtChar &= ~TT2$M_PASTHRU;
  365.   if ((mysts = sys$qiow (
  366.                0,
  367.                _kbhitChan_,
  368.                IO$_SETMODE,
  369.                &iosb,
  370.                0,
  371.                0,
  372.                &CharBuf,
  373.                12,
  374.                0,
  375.                0,
  376.                0,
  377.                0)) & 01) mysts = iosb.sts;
  378.   (void) sys$dassgn (
  379.       _kbhitChan_);
  380.   _kbhitChan_ = 0;
  381.   if (!(mysts & 01)) {
  382.     fprintf(stderr,"\nFailed to reset terminal characteristics!");
  383.     (void) lib$signal(mysts);
  384.   }
  385. }
  386.  
  387. unsigned int exsts;
  388.  
  389. static struct {
  390.     int link;
  391.     void *rtn;
  392.     int argcnt;
  393.     int *stsaddr;
  394.    } exhblk = { 0, &(kbhit_handler), 1, &(exsts)};
  395.  
  396. int kbhit()
  397. {
  398.   int sts = 1;
  399.  
  400.   struct {
  401.     unsigned short TypAhdCnt;
  402.     char FirstChar;
  403.     char Reserved[5];
  404.   } TypCharBuf;
  405.  
  406.   if (_kbhitChan_ == 0) {
  407.     if ((sts = sys$assign (
  408.                &kbdev_desc,
  409.                &_kbhitChan_,
  410.                0,
  411.                0)) & 1 == 0) lib$stop(sts);
  412.     if ((sts = sys$qiow (
  413.                0,
  414.                _kbhitChan_,
  415.                IO$_SENSEMODE,
  416.                &iosb,
  417.                0,
  418.                0,
  419.                &CharBuf,
  420.                12,
  421.                0,
  422.                0,
  423.                0,
  424.                0)) & 01) sts = iosb.sts;
  425.     if (sts & 01) {
  426.       if (!(CharBuf.Class & DC$_TERM)) {
  427.         fprintf(stderr,"\nNot running on a terminal");
  428.         exitPGP(1);
  429.       } else {
  430.         OldCharBuf.Mode = CharBuf.Mode;
  431.         OldCharBuf.ExtChar = CharBuf.ExtChar;
  432.         CharBuf.Mode |= TT$M_NOECHO;
  433.         CharBuf.ExtChar |= TT2$M_PASTHRU;
  434.         if ((sts = sys$qiow (
  435.                0,
  436.                _kbhitChan_,
  437.                IO$_SETMODE,
  438.                &iosb,
  439.                0,
  440.                0,
  441.                &CharBuf,
  442.                12,
  443.                0,
  444.                0,
  445.                0,
  446.                0)) & 01) sts = iosb.sts;
  447.         if (sts & 01) {
  448.       /*
  449.       **  Declare Exit Handler
  450.       */
  451.            (void) sys$dclexh (&exhblk);
  452.         } else {
  453.               fprintf(stderr,"\nFailed to set terminal characteristics!");
  454.           (void) lib$signal(sts);
  455.               exitPGP(1);
  456.             }
  457.       }
  458.     }
  459.   }
  460.   /*
  461.   **  Get typeahead count
  462.   */
  463.   if ((sts = sys$qiow (
  464.                0,
  465.                _kbhitChan_,
  466.                IO$_SENSEMODE | IO$M_TYPEAHDCNT,
  467.                &iosb,
  468.                0,
  469.                0,
  470.                &TypCharBuf,
  471.                8,
  472.                0,
  473.                0,
  474.                0,
  475.                0)) & 01) sts = iosb.sts;
  476.   if (sts & 01) return(TypCharBuf.TypAhdCnt>0);
  477.   (void) lib$signal(sts);
  478.   exitPGP(1);
  479. }
  480.  
  481. int getch()
  482. {
  483.   unsigned int sts;
  484.   volatile char CharBuf;
  485.  
  486.   if ((sts = sys$qiow (
  487.               0,
  488.               _kbhitChan_,
  489.               IO$_READVBLK,
  490.               &iosb,
  491.               0,
  492.               0,
  493.               &CharBuf,
  494.               1,
  495.               0,
  496.               0,
  497.               0,
  498.               0)) & 01) sts = iosb.sts;
  499.   if (sts & 01) return ((int) CharBuf);
  500.   fprintf(stderr,"\nFailed to get character");
  501.   (void) lib$signal(sts);
  502. }
  503.  
  504. ttynorm()
  505. {
  506.   int sts;
  507.  
  508.   if (_kbhitChan_ != 0) {
  509.     (void) SYS$CANEXH(&exhblk);
  510.     kbhit_handler(&sts);
  511.   }
  512. }
  513.  
  514. void ttycbreak ()
  515. {
  516.    ttynorm();
  517. }
  518.  
  519. unsigned long    vms_clock_bits[2];    /* VMS Hardware Clock */
  520. const long    vms_ticks_per_update = 100000L; /* Clock update int. */
  521.  
  522. #endif /* VMS */
  523.  
  524.  
  525.  
  526. /*========================================================================*/
  527. /*
  528.  * AMIGA
  529.  */
  530.  
  531. #ifdef AMIGA    /* Amiga-specific stuff */
  532.  
  533. #include <exec/types.h>
  534. #include <exec/memory.h>
  535. #include <exec/ports.h>
  536. #include <libraries/dosextens.h>
  537. #ifdef LATTICE
  538. #include <proto/exec.h> 
  539. #include <proto/dos.h> 
  540. #endif /* LATTICE */
  541. extern FILE *pgpout;
  542. extern int aecho;
  543.  
  544. FILE *tmpfile()
  545. {
  546.   FILE *fp;
  547.  
  548.   if ((fp=fopen("tmpfile.tmp","w+b"))==NULL) {
  549.     perror("tmpfile.tmp");
  550.     return(NULL);
  551.   }
  552.   return(fp);
  553.  
  554. }
  555.  
  556. /* amiga version of getch() 
  557.    Cor Bosman , jul-22-92 
  558. */
  559.  
  560.  
  561. sendpacket(struct MsgPort *rec,LONG action,LONG arg1) 
  562. {
  563.   struct StandardPacket *pkt;
  564.   struct msgPort *rp;
  565.   LONG res1 = 0L;
  566.  
  567.   if (rp = (struct MsgPort *)CreatePort(NULL,0L)) {
  568.     if (pkt = (struct StandardPacket *)\
  569.      AllocMem(sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR)) {
  570.        pkt->sp_Msg.mn_Node.ln_Name = (BYTE *)&pkt->sp_Pkt;
  571.        pkt->sp_Pkt.dp_Link = &pkt->sp_Msg;
  572.        pkt->sp_Pkt.dp_Port = rp;
  573.        pkt->sp_Pkt.dp_Type = action;
  574.        pkt->sp_Pkt.dp_Arg1 = arg1;
  575.        PutMsg(rec,&pkt->sp_Msg);
  576.        WaitPort(rp);
  577.        GetMsg(rp);
  578.        res1 = pkt->sp_Pkt.dp_Res1;
  579.        FreeMem((UBYTE*)pkt,sizeof(struct StandardPacket));
  580.      }
  581.      DeletePort(rp);
  582.     }
  583.     return(res1);
  584.  
  585. }
  586.  
  587. /* ttycbreak for amiga.
  588.  * Cor Bosman , jul-30-92
  589. */
  590.  
  591. void ttycbreak()
  592. {
  593.   BPTR in,out;
  594.   char buf[128];
  595.   struct MsgPort *ch;
  596.  
  597.   in=Input();
  598.   out=Output();
  599.   ch = ((struct FileHandle *)BADDR(in))->fh_Type;
  600.   sendpacket(ch,ACTION_SCREEN_MODE,-1L);
  601. }
  602.  
  603. /* ttynorm for amiga
  604.  * Cor Bosman , jul-30-92
  605. */
  606.  
  607. void ttynorm()
  608. {
  609.  
  610.   BPTR in,out;
  611.   char buf[128];
  612.   struct MsgPort *ch;
  613.  
  614.   in=Input();
  615.   out=Output();
  616.   ch = ((struct FileHandle *)BADDR(in))->fh_Type;
  617.   sendpacket(ch,ACTION_SCREEN_MODE,0L);
  618. }
  619.  
  620. char getch(void)
  621. {
  622.   char buf[128];
  623.   BPTR in,out;
  624.  
  625.   in = Input();
  626.   out = Output();
  627.   Read(in,buf,1);
  628.   if (aecho) 
  629.     Write(out, buf, 1);
  630.   return(buf[0]);
  631. }
  632.  
  633. /* kbhit() function for amiga.
  634.  * Cor Bosman , jul-30-92
  635. */
  636.  
  637. int kbhit() 
  638. {
  639.   if(WaitForChar(Input(), 1)) return 1;
  640.   return 0;
  641. }
  642.  
  643. #ifdef LATTICE
  644.  
  645. /*
  646.  *  Lattice-C  ^C-Handler 
  647. */
  648.  
  649. int CXBRK()
  650. {
  651.   BPTR in,out;
  652.   struct MsgPort *ch;
  653.   in=Input();
  654.   out=Output();
  655.  
  656.   /* it might happen we catch a ^C while in cbreak mode.
  657.    * so always set the screen to the normal mode.
  658.   */
  659.  
  660.   ch = ((struct FileHandle *)BADDR(in))->fh_Type;
  661.   sendpacket(ch, ACTION_SCREEN_MODE, 0L);
  662.  
  663.  
  664.   fprintf(pgpout, "\n*** Program Aborted.\n");
  665.   exitPGP(6); /* INTERRUPT */
  666. }
  667. #endif
  668.  
  669. #endif /* AMIGA */
  670.  
  671.  
  672.  
  673. /*===========================================================================*/
  674. /*
  675.  * other stuff for non-MSDOS systems
  676.  */
  677.  
  678. #ifdef ATARI
  679. #include <string.h>
  680. #endif
  681.  
  682. #if !defined(MSDOS) && !defined(ATARI)
  683. #include <ctype.h>
  684. char *strlwr(char *s)
  685. {    /*
  686.     **        Turns string s into lower case.
  687.     */
  688.     int c;
  689.     char *p = s;
  690.     while (c = *p)
  691.         *p++ = tolower(c);
  692.     return(s);
  693. }
  694. #endif /* !MSDOS && !ATARI */
  695.  
  696.  
  697. #ifdef strstr
  698. #undef strstr
  699. /* Not implemented on some systems - return first instance of s2 in s1 */
  700. char *mystrstr (char *s1, char *s2)
  701. {    int i;
  702.     char *strchr();
  703.  
  704.     if (!s2 || !*s2)
  705.         return s1;
  706.     for ( ; ; )
  707.     {    if (!(s1 = strchr (s1, *s2)))
  708.             return s1;
  709.         for (i=1; s2[i] && (s1[i]==s2[i]); ++i)
  710.             ;
  711.         if (!s2[i])
  712.             return s1;
  713.         ++s1;
  714.     }
  715. }
  716. #endif /* strstr */
  717.  
  718.  
  719. #ifdef fopen
  720. #undef fopen
  721.  
  722. #ifdef ATARI
  723. #define F_BUF_SIZE 8192  /* seems to be a good value ... */
  724.  
  725. FILE *myfopen(const char *filename, const char *mode)
  726. /* Open streams with larger buffer to increase disk I/O speed. */
  727. /* Adjust F_BUF_SIZE to change buffer size.                    */
  728. {
  729.     FILE *f;
  730.  
  731.     if ( (f = fopen(filename, mode)) != NULL )
  732.         if (setvbuf(f, NULL, _IOFBF, F_BUF_SIZE)) /* no memory? */
  733.         {
  734.             fclose(f);                 /* then close it again */
  735.             f = fopen(filename, mode); /* and try again in normal mode */
  736.         }
  737.     return(f);                         /* return either handle or NULL */
  738. }
  739.     
  740. #else /* ATARI */
  741.  
  742. /* Remove "b" from 2nd arg */
  743. FILE *myfopen(char *filename, char *type)
  744. {    char buf[10];
  745.  
  746.     buf[0] = *type++;
  747.     if (*type=='b')
  748.         ++type;
  749.     strcpy(buf+1,type);
  750.     return fopen(filename, buf);
  751. }
  752. #endif /* not ATARI */
  753. #endif /* fopen */
  754.